package com.ny.zmb.openapi.controller;

import com.alibaba.fastjson.JSONObject;
import com.google.gson.JsonObject;
import com.ny.zmb.openapi.config.YsConfig;
import com.ny.zmb.openapi.controller.entity.IPYs;
import com.ny.zmb.openapi.controller.entity.OrderRefund;
import com.ny.zmb.openapi.controller.entity.OrdersOnline;
import com.ny.zmb.openapi.controller.entity.Result;
import com.ny.zmb.openapi.util.*;
import com.ny.zmb.openapi.ysutil.YinShengClient;
import com.ny.zmb.openapi.ysutil.YsHttpUtil;
import com.ny.zmb.openapi.ysutil.base.EYinShengBase;
import com.ny.zmb.openapi.ysutil.base.HeadResponseCommand;
import com.ny.zmb.openapi.ysutil.base.MerchantHeadRequestCommand;
import com.ny.zmb.openapi.ysutil.common.ServiceEnum;
import com.ny.zmb.openapi.ysutil.common.YsPayConstant;
import com.ny.zmb.openapi.ysutil.scancode.BackCodePayReqCommand;
import com.ny.zmb.openapi.ysutil.scancode.BackCodePayRespCommand;
import com.ny.zmb.openapi.ysutil.utils.JsonParser;
import com.ny.zmb.openapi.ysutil.utils.YinshengLogger;
import org.apache.commons.lang.StringUtils;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@CrossOrigin
@RequestMapping("wallet")
@RestController
public class OrdersOnlineController extends EYinShengBase {

    @Resource
    private YsUtil ycutil;
    @Resource
    private YsHttpUtil ysHttpUtil;

    /**
     * 商户端私钥证书
     * 生产环境需要使用自己生产的私钥证书
     */
    private String YS_PUBLIC_CER_PATH = new YsConfig().getYsPublicCerPath();


    /**
     * 请求地址域名
     */
    private static final String HTTP_NET = "https://ysgate.ysepay.com";

    /**
     * 订单总额分账登记
     */
    @PostMapping("divRegist")
    public Result divRegist(@RequestBody OrdersOnline ordersOnline) throws Exception{
        try {
            BackCodePayReqCommand command = new BackCodePayReqCommand();
            JSONObject send = ysHttpUtil.send(ServiceEnum.WALLET_PAY_BARCODE, YsPayConstant.ENV_TEST, MERCHANT_PRX, MERCHANT_PRX_PWD,ServiceEnum.WALLET_PAY_BARCODE.getApiName(), command);
            return Result.ok(send);
        }catch (Exception var){
            return Result.fail(var.getMessage());
        }
    }


    /**
     * 线上分账登记查询
     */
    @GetMapping("divQuery")
    public Result divQuery(String orderId,String sysFlag) throws Exception{
        String httpUrl = HTTP_NET+"/openapi/trade/division/settlableAmt/settlableAmtReg";
        Map<String,Object> dataMap = new HashMap<>();
        dataMap.put("sysFlag",sysFlag);
        Map<String,String> reqMap = ycutil.resultMap("orderId",orderId,dataMap,"unify.division.online.divQuery");
        String key = reqMap.get("resultKey");
        reqMap.remove("resultKey");
        /** 7、发送http请求获取返回结果，请求地址以文档为准*/
        try {
            String result = HttpRequestUtil.getDoPostResponse(httpUrl, reqMap, "UTF-8", null, 20*1000);
            byte[] res = Base64.decodeBase64(result);
            Map<String, String> resMap = (Map<String, String>) JSONObject.parse(new String(res,"UTF-8"));
            System.out.println("http请求返回的结果为:"+JSONObject.toJSONString(resMap));

            /** 8、对结果进行解密，并使用银盛公钥验签*/
            if(StringUtils.isNotBlank(resMap.get("sign"))) {
                byte[] srcData = GMSignUtils.getSignDataStr1(resMap).getBytes("UTF-8");
                GMCertInfo verifyCertInfo = GMSignUtils.getVerifyCertInfo(YS_PUBLIC_CER_PATH);
                boolean validateSignResult = GMSignUtils.verifyMsgSignSM2(verifyCertInfo,Base64.decodeBase64(resMap.get("sign")),srcData);
                if(!validateSignResult){
                    System.out.println("验签失败");
                    return Result.fail("签名验证失败");
                }
            }else{
                System.out.println("验签失败,未返回加签信息,可能是未配置发起方或者未配置发起方的证书类型,返回结果提示为:{}"+resMap.get("msg"));
                return Result.fail(reqMap.get("msg"));
            }

            /** 9、针对自己的业务，根据返回的结果的code 和 subCode 做接入方的业务处理*/
            /** 10、使用上面生成的加密密钥key，解密返回的业务参数*/
            if(StringUtils.isNotBlank(resMap.get("businessData"))) {
                byte[] data_ = Base64.decodeBase64(resMap.get("businessData"));
                byte[] data = AESUtil.decrypt(data_, ByteUtil.hexStringToBytes(key));
                String s = new String(data, "UTF-8");
                resMap.put("businessData", s);
                System.out.println("解密后的业务参数:"+new String(data,"UTF-8"));
                return Result.ok(JSONObject.parseObject(s));
            }
            return Result.fail("查询失败");
        } catch (Exception e) {
            e.printStackTrace();
            return Result.fail(e.getMessage());
        }
    }

    /**
     * 分账规则登记撤销
     */
    @GetMapping("cancelDivisionRegister")
    public Result cancelDivisionRegister(String orderId,String requestFlag,String merLogNo) throws Exception{
        String httpUrl = HTTP_NET+"/openapi/trade/division/settlableAmt/settlableAmtReg";
        Map<String,Object> dataMap = new HashMap<>();
        dataMap.put("requestFlag",requestFlag);
        dataMap.put("merLogNo",merLogNo);
        Map<String,String> reqMap = ycutil.resultMap("orderId",orderId,dataMap,"trade.division.online.cancelDivisionRegister");
        String key = reqMap.get("resultKey");
        reqMap.remove("resultKey");
        /** 7、发送http请求获取返回结果，请求地址以文档为准*/
        try {
            String result = HttpRequestUtil.getDoPostResponse(httpUrl, reqMap, "UTF-8", null, 20*1000);
            byte[] res = Base64.decodeBase64(result);
            Map<String, String> resMap = (Map<String, String>) JSONObject.parse(new String(res,"UTF-8"));
            System.out.println("http请求返回的结果为:"+JSONObject.toJSONString(resMap));

            /** 8、对结果进行解密，并使用银盛公钥验签*/
            if(StringUtils.isNotBlank(resMap.get("sign"))) {
                byte[] srcData = GMSignUtils.getSignDataStr1(resMap).getBytes("UTF-8");
                GMCertInfo verifyCertInfo = GMSignUtils.getVerifyCertInfo(YS_PUBLIC_CER_PATH);
                boolean validateSignResult = GMSignUtils.verifyMsgSignSM2(verifyCertInfo,Base64.decodeBase64(resMap.get("sign")),srcData);
                if(!validateSignResult){
                    System.out.println("验签失败");
                    return Result.fail("签名验证失败");
                }
            }else{
                System.out.println("验签失败,未返回加签信息,可能是未配置发起方或者未配置发起方的证书类型,返回结果提示为:{}"+resMap.get("msg"));
                return Result.fail(resMap.get("msg"));
            }

            /** 9、针对自己的业务，根据返回的结果的code 和 subCode 做接入方的业务处理*/
            /** 10、使用上面生成的加密密钥key，解密返回的业务参数*/
            if(StringUtils.isNotBlank(resMap.get("businessData"))) {
                byte[] data_ = Base64.decodeBase64(resMap.get("businessData"));
                byte[] data = AESUtil.decrypt(data_, ByteUtil.hexStringToBytes(key));
                String s = new String(data, "UTF-8");
                resMap.put("businessData", s);
                System.out.println("解密后的业务参数:"+new String(data,"UTF-8"));
                return Result.ok(JSONObject.parseObject(s));
            }
            return Result.fail("查询失败");
        } catch (Exception e) {
            e.printStackTrace();
            return Result.fail("查询失败");
        }
    }

    /**
     * 分账回退
     */
    @GetMapping("divisionWithdraw")
    public Result divisionWithdraw(String orderId,String mercId,String backoffAmt,String backOfOrderId,String oriMercId,String sponsorMercId) throws Exception{
        String httpUrl = HTTP_NET+"/openapi/trade/division/settlableAmt/settlableAmtReg";
        Map<String,Object> dataMap = new HashMap<>();
        dataMap.put("mercId",mercId);
        dataMap.put("backoffAmt",backoffAmt);
        dataMap.put("backOfOrderId",backOfOrderId);
        dataMap.put("oriMercId",oriMercId);
        dataMap.put("sponsorMercId",sponsorMercId);
        Map<String,String> reqMap = ycutil.resultMap("orderId",orderId,dataMap,"trade.division.online.divisionWithdraw");
        String key = reqMap.get("resultKey");
        reqMap.remove("resultKey");
        /** 7、发送http请求获取返回结果，请求地址以文档为准*/
        try {
            String result = HttpRequestUtil.getDoPostResponse(httpUrl, reqMap, "UTF-8", null, 20*1000);
            byte[] res = Base64.decodeBase64(result);
            Map<String, String> resMap = (Map<String, String>) JSONObject.parse(new String(res,"UTF-8"));
            System.out.println("http请求返回的结果为:"+JSONObject.toJSONString(resMap));

            /** 8、对结果进行解密，并使用银盛公钥验签*/
            if(StringUtils.isNotBlank(resMap.get("sign"))) {
                byte[] srcData = GMSignUtils.getSignDataStr1(resMap).getBytes("UTF-8");
                GMCertInfo verifyCertInfo = GMSignUtils.getVerifyCertInfo(YS_PUBLIC_CER_PATH);
                boolean validateSignResult = GMSignUtils.verifyMsgSignSM2(verifyCertInfo,Base64.decodeBase64(resMap.get("sign")),srcData);
                if(!validateSignResult){
                    System.out.println("验签失败");
                    return Result.fail("验证失败");
                }
            }else{
                System.out.println("验签失败,未返回加签信息,可能是未配置发起方或者未配置发起方的证书类型,返回结果提示为:{}"+resMap.get("msg"));
                return Result.fail(resMap.get("msg"));
            }

            /** 9、针对自己的业务，根据返回的结果的code 和 subCode 做接入方的业务处理*/
            /** 10、使用上面生成的加密密钥key，解密返回的业务参数*/
            if(StringUtils.isNotBlank(resMap.get("businessData"))) {
                byte[] data_ = Base64.decodeBase64(resMap.get("businessData"));
                byte[] data = AESUtil.decrypt(data_, ByteUtil.hexStringToBytes(key));
                String s = new String(data, "UTF-8");
                resMap.put("businessData", s);
                System.out.println("解密后的业务参数:"+new String(data,"UTF-8"));
                return Result.ok(JSONObject.parseObject(s));
            }
            return Result.fail("查询失败");
        } catch (Exception e) {
            e.printStackTrace();
            return Result.fail("查询失败");
        }
    }

    /**
     * 分账白名单配置
     */
    @PostMapping("modifyDivRuleWhiteList")
    public Result modifyDivRuleWhiteList(@RequestBody IPYs ipYs) throws Exception{
        String httpUrl = HTTP_NET+"/openapi/trade/division/settlableAmt/settlableAmtReg";
        Map<String,Object> dataMap = new HashMap<>();
        dataMap.put("divOrgNo",ipYs.getDivOrgNo());
        Map<String,String> reqMap = ycutil.resultMap("whiteLists",ipYs.getDivOrgNo(),dataMap,"trade.division.online.modifyDivRuleWhiteList");
        String key = reqMap.get("resultKey");
        reqMap.remove("resultKey");
        /** 7、发送http请求获取返回结果，请求地址以文档为准*/
        try {
            String result = HttpRequestUtil.getDoPostResponse(httpUrl, reqMap, "UTF-8", null, 20*1000);
            byte[] res = Base64.decodeBase64(result);
            Map<String, String> resMap = (Map<String, String>) JSONObject.parse(new String(res,"UTF-8"));
            System.out.println("http请求返回的结果为:"+JSONObject.toJSONString(resMap));

            /** 8、对结果进行解密，并使用银盛公钥验签*/
            if(StringUtils.isNotBlank(resMap.get("sign"))) {
                byte[] srcData = GMSignUtils.getSignDataStr1(resMap).getBytes("UTF-8");
                GMCertInfo verifyCertInfo = GMSignUtils.getVerifyCertInfo(YS_PUBLIC_CER_PATH);
                boolean validateSignResult = GMSignUtils.verifyMsgSignSM2(verifyCertInfo,Base64.decodeBase64(resMap.get("sign")),srcData);
                if(!validateSignResult){
                    System.out.println("验签失败");
                    return Result.fail("签名验证失败");
                }
            }else{
                System.out.println("验签失败,未返回加签信息,可能是未配置发起方或者未配置发起方的证书类型,返回结果提示为:{}"+resMap.get("msg"));
                return Result.fail(resMap.get("msg"));
            }

            /** 9、针对自己的业务，根据返回的结果的code 和 subCode 做接入方的业务处理*/
            /** 10、使用上面生成的加密密钥key，解密返回的业务参数*/
            if(StringUtils.isNotBlank(resMap.get("businessData"))) {
                byte[] data_ = Base64.decodeBase64(resMap.get("businessData"));
                byte[] data = AESUtil.decrypt(data_, ByteUtil.hexStringToBytes(key));
                String s = new String(data, "UTF-8");
                resMap.put("businessData", s);
                System.out.println("解密后的业务参数:"+new String(data,"UTF-8"));
                return Result.ok(JSONObject.parseObject(s));
            }
            throw new Exception("查询失败");
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("查询失败");
        }
    }

    /**
     * 分账退款
     */
    @PostMapping("divRefund")
    public Result divRefund(@RequestBody OrderRefund orderRefund) throws Exception{
        String httpUrl = HTTP_NET+"/openapi/unify/division/online/divRefund";
        Map<String,Object> dataMap = new HashMap<>();
        dataMap.put("orderId",orderRefund.getOrderId());
        dataMap.put("tradeSn",orderRefund.getTradeSn());
        dataMap.put("shopDate",orderRefund.getShopDate());
        dataMap.put("amount",orderRefund.getAmount());
        dataMap.put("refundReason",orderRefund.getRefundReason());
        dataMap.put("refundOrderId",orderRefund.getRefundOrderId());
        dataMap.put("isDivistion",orderRefund.getIsDivistion());
        dataMap.put("divisionMode",orderRefund.getDivisionMode());
        dataMap.put("notifyUrl",orderRefund.getNotifyUrl());
        dataMap.put("msgCode",orderRefund.getMsgCode());
        dataMap.put("srcIP",orderRefund.getSrcIP());
        dataMap.put("refundDivInfoList",orderRefund.getRefundDivInfoList());
        Map<String,String> reqMap = ycutil.resultMap("originalDivInfoList",orderRefund.getOriginalDivInfoList(),dataMap,"unify.division.online.divRefund");
        String key = reqMap.get("resultKey");
        reqMap.remove("resultKey");
        /** 7、发送http请求获取返回结果，请求地址以文档为准*/
        try {
            String result = HttpRequestUtil.getDoPostResponse(httpUrl, reqMap, "UTF-8", null, 20*1000);
            byte[] res = Base64.decodeBase64(result);
            Map<String, String> resMap = (Map<String, String>) JSONObject.parse(new String(res,"UTF-8"));
            System.out.println("http请求返回的结果为:"+JSONObject.toJSONString(resMap));

            /** 8、对结果进行解密，并使用银盛公钥验签*/
            if(StringUtils.isNotBlank(resMap.get("sign"))) {
                byte[] srcData = GMSignUtils.getSignDataStr1(resMap).getBytes("UTF-8");
                GMCertInfo verifyCertInfo = GMSignUtils.getVerifyCertInfo(YS_PUBLIC_CER_PATH);
                boolean validateSignResult = GMSignUtils.verifyMsgSignSM2(verifyCertInfo,Base64.decodeBase64(resMap.get("sign")),srcData);
                if(!validateSignResult){
                    System.out.println("验签失败");
                    return Result.fail("签名验证失败");
                }
            }else{
                System.out.println("验签失败,未返回加签信息,可能是未配置发起方或者未配置发起方的证书类型,返回结果提示为:{}"+resMap.get("msg"));
                return Result.fail(resMap.get("msg"));
            }

            /** 9、针对自己的业务，根据返回的结果的code 和 subCode 做接入方的业务处理*/
            /** 10、使用上面生成的加密密钥key，解密返回的业务参数*/
            if(StringUtils.isNotBlank(resMap.get("businessData"))) {
                byte[] data_ = Base64.decodeBase64(resMap.get("businessData"));
                byte[] data = AESUtil.decrypt(data_, ByteUtil.hexStringToBytes(key));
                String s = new String(data, "UTF-8");
                resMap.put("businessData", s);
                System.out.println("解密后的业务参数:"+new String(data,"UTF-8"));
                return Result.ok(JSONObject.parseObject(s));
            }
            return Result.fail("查询失败");
        } catch (Exception e) {
            e.printStackTrace();
            return Result.fail("查询失败");
        }
    }
}
